﻿def dummy():

  def add(params):

    def EXEC1(value2, value1, ):
      result = value1 + value2
      return locals()
    step_result = EXEC1(params['value2'], params['value1'], )
    params.update(step_result)

    results = {}
    results['result'] = params['result']
    return results

  def add_addition(params):

    def EXEC1(data, ):
      data['additions'].append({'date': '', 'reason': ''})
      return locals()
    step_result = EXEC1(params['data'], )
    params.update(step_result)

    results = {}
    return results

  def add_cancellation(params):

    def EXEC1(data, ):
      data['cancellations'].append({'start date': '', 'end date': '', 'reason': ''})
      return locals()
    step_result = EXEC1(params['data'], )
    params.update(step_result)

    results = {}
    return results

  def add_new_course(params):
    params['course definition'] = knowledge_get('course definition')
    params['view'] = knowledge_get('course details view')

    step_params = {}
    step_params.update(params)
    step_params['definition'] = params['course definition']
    step_result = create_data_from_definition(step_params)
    params['course data'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = knowledge_get_or_literal('app context')
    step_result = get_value(step_params)
    params['app context'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['app context']
    step_params['data'] = params['course data']
    step_params['view'] = params['view']
    step_params['parent context'] = params['context']
    step_params['title'] = 'Add New Course'
    step_result = open_view(step_params)

    results = {}
    return results

  def append_items_to_list(params):

    def EXEC1(items, list, ):
      list.extend(items)
      return locals()
    step_result = EXEC1(params['items'], params['list'], )
    params.update(step_result)

    results = {}
    return results

  def append_to_list(params):

    def EXEC1(list, value, ):
      list.append(value)
      return locals()
    step_result = EXEC1(params['list'], params['value'], )
    params.update(step_result)

    results = {}
    return results

  def apply_change_list(params):

    def EXEC1(data, change_list, ):
      for changes in change_list:
        data = execute_knowledge_piece('apply changes inplace', {'data': data, 'changes': changes})['data']
      return locals()
    step_result = EXEC1(params['data'], params['change list'], )
    params['data'] = step_result['data']

    results = {}
    results['data'] = params['data']
    return results

  def apply_changes_inplace(params):

    def EXEC1(changes, data, ):
      if changes is None:
        pass
      elif type(changes) is dict:
        if type(data) is not dict:
          raise Exception("The type of 'changes' object should be the same as of the data")
        else:
          for key, item_changes in changes.iteritems():
            if item_changes is None:
              data.pop(key, None)
            else:
              value = data.get(key, None)
              if value is None:
                data[key] = item_changes
              else:
                new_value = execute_knowledge_piece('apply changes inplace', {'data': value, 'changes': item_changes})['data']
                data[key] = new_value
      elif type(changes) is list:
        if type(data) is not list:
          raise Exception("The type of 'changes' object should be the same as of the data")
        else:
          changes_left = list(changes)
          item_index = 0
          for item in list(data):
            if type(item) is dict and 'id' in item:
              id = item['id']
              index = 0
              deleted = False
              for item_changes in list(changes_left):
                if type(item_changes) is not dict or 'id' not in item_changes or item_changes['id'] != id:
                  index = index + 1
                  continue
                del changes_left[index]
                if item_changes.get('deleted'):
                  deleted = True
                  continue
                if deleted:
                  data[item_index] = item_changes
                else:
                  data[item_index] = execute_knowledge_piece('apply changes inplace', {'data': item, 'changes': item_changes})['data']
                deleted = False
              if deleted:
                del data[item_index]
              else:
                item_index = item_index + 1
            else:
              index = 0
              found = False
              for item_changes in list(changes_left):
                if type(item_changes) is dict and 'id' in item_changes:
                  index = index + 1
                  continue
                del changes_left[index]
                data[item_index] = item_changes
                found = True
                break
              if not found:
                del data[item_index]
              else:
                item_index = item_index + 1
          for item in changes_left:
            data.append(item)
      else:
        data = changes
      return locals()
    step_result = EXEC1(params['changes'], params['data'], )
    params.update(step_result)

    results = {}
    results['data'] = params['data']
    return results

  def apply_common_attributes_to_wpf_element(params):

    def EXEC1(element, attributes, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import HorizontalAlignment
      from System.Windows import VerticalAlignment
      from System.Windows.Controls import Dock
      from System.Windows.Controls import DockPanel
      
      if 'horizontal alignment' in attributes:
        h_align = attributes.get('horizontal alignment')
        if h_align == 'left':
          element.HorizontalAlignment = HorizontalAlignment.Left
        elif h_align == 'center':
          element.HorizontalAlignment = HorizontalAlignment.Center
        elif h_align == 'right':
          element.HorizontalAlignment = HorizontalAlignment.Right
      if 'vertical alignment' in attributes:
        v_align = attributes.get('vertical alignment')
        if v_align == 'left':
          element.VerticalAlignment = VerticalAlignment.Left
        elif v_align == 'center':
          element.VerticalAlignment = VerticalAlignment.Center
        elif v_align == 'right':
          element.VerticalAlignment = VerticalAlignment.Right
      if 'dock' in attributes:
        dock_name = attributes.get('dock')
        dock = Dock.Top
        if dock_name == 'bottom':
          dock = Dock.Bottom
        if dock_name == 'left':
          dock = Dock.Left
        if dock_name == 'right':
          dock = Dock.Right
        DockPanel.SetDock(element, dock)
      if 'font size' in attributes:
        element.FontSize = attributes.get('font size')
      if 'width' in attributes:
        element.Width = attributes.get('width')
      if 'height' in attributes:
        element.Height = attributes.get('height')
      return locals()
    step_result = EXEC1(params['wpf element'], params['attributes'], )
    params.update(step_result)

    results = {}
    return results

  def calculate_course_schedule_data(params):
    params['holidays'] = knowledge_get('russian holidays')

    def EXEC1(data, holidays, ):
      start_date = data['start date']
      num_lessons = data['number of lessons']
      result = execute_knowledge_piece('calculate schedule dates', {
        'start_date': start_date,
        'count': num_lessons,
        'schedule': data['schedule'],
        'holidays': holidays,
        'cancellations': data['cancellations'],
        'additions': data['additions'],
        })
      dates = result['dates']
      all_dates = result['all schedule dates']
      finish_date = dates[num_lessons - 1]
      test_lessons = data['test lessons']
      for date in all_dates:
        reason = date['reason'] or []
        if type(reason) is not list:
          reason = [reason]
        lesson = date['lesson #']
        if lesson is not None:
          if lesson == 1:
            reason.append('Start')
          for test_num in range(len(test_lessons)):
            test_lesson = test_lessons[test_num]
            if lesson == test_lesson:
              reason.append('Test %d' % (test_num + 1))
          if lesson == num_lessons:
            reason.append('Finish')
        if date['status'] == 'removed':
          if date['is holiday']:
            date['lesson #'] = 'Holiday'
          else:
            date['lesson #'] = 'Cancelled'
        if len(reason) > 0:
          date['reason'] = ', '.join(reason)
      data['holidays'] = [holiday for holiday in holidays if start_date <= holiday['start date'] <= finish_date or start_date <= holiday['end date'] <= finish_date]
      data['lesson dates'] = [{'lesson #': lesson + 1, 'date': dates[lesson]} for lesson in range(num_lessons)]
      data['all schedule dates'] = all_dates
      data['test dates'] = [(dates[lesson - 1] if 0 < lesson <= num_lessons else None) for lesson in test_lessons]
      data['finish date'] = finish_date
      return locals()
    step_result = EXEC1(params['data'], params['holidays'], )
    params.update(step_result)

    results = {}
    results['data'] = params['data']
    return results

  def calculate_schedule_dates(params):

    def EXEC1(count, schedule, cancellations, holidays, additions, start_date, ):
      from datetime import date
      #cancellations = holidays + cancellations
      removed_dates = dict()
      holiday_dates = set()
      for cancellations_collection in [holidays, cancellations]:
        for cancellation in cancellations_collection:
          start = cancellation['start date']
          end = cancellation['end date']
          reason = cancellation['reason']
          cur_date = start
          while cur_date <= end:
            removed_dates[cur_date] = removed_dates.get(cur_date, []) + [reason]
            if cancellations_collection is holidays:
              holiday_dates.add(cur_date)
            cur_date = date.fromordinal(cur_date.toordinal() + 1)
      added_dates = dict((addition['date'], addition['reason']) for addition in additions)
      dates = []
      all_dates = []
      current_date = start_date
      #write_to_log('locals: %s', repr(locals()))
      date_number = 0
      while date_number < count:
        week_day = current_date.weekday()
        #write_to_log('date_number: %d, week_day: %d', (date_number, week_day))
        status = None
        reason = None
        if current_date in added_dates:
          status = 'added'
          reason = added_dates[current_date]
        elif week_day in schedule:
          if current_date in removed_dates:
            status = 'removed'
            reason = removed_dates[current_date]
          else:
            status = 'by schedule'
        if status is not None:
          all_dates.append({'lesson #': (date_number + 1 if status != 'removed' else None), 'date': current_date, 'status': status, 'reason': reason, 'is holiday': current_date in holiday_dates})
          if status != 'removed':
            dates.append(current_date)
            date_number = date_number + 1
        current_date = date.fromordinal(current_date.toordinal() + 1)
      return locals()
    step_result = EXEC1(params['count'], params['schedule'], params['cancellations'], params['holidays'], params['additions'], params['start_date'], )
    params['dates'] = step_result['dates']
    params['all schedule dates'] = step_result['all_dates']

    results = {}
    results['dates'] = params['dates']
    results['all schedule dates'] = params['all schedule dates']
    return results

  def cancel_selected_lessons(params):

    def EXEC1(selected_items, data, ):
      start_date = None
      end_date = None
      prev_lesson_num = None
      def add_cancellation(data, start_date, end_date):
        if start_date and end_date:
          data['cancellations'].append({'start date': start_date, 'end date': end_date, 'reason': ''})
      for lesson in sorted(selected_items, key = lambda item: item.get('lesson #')):
        if type(lesson) is dict:
          lesson_num = lesson.get('lesson #')
          lesson_date = lesson.get('date')
          if lesson_num is not None and lesson_date:
            if prev_lesson_num and lesson_num > prev_lesson_num + 1:
              add_cancellation(data, start_date, end_date)
              start_date = None
              end_date = None
            if not start_date or lesson_date < start_date:
              start_date = lesson_date
            if not end_date or lesson_date > end_date:
              end_date = lesson_date
            prev_lesson_num = lesson_num
      add_cancellation(data, start_date, end_date)
      return locals()
    step_result = EXEC1(params['selected items'], params['data'], )
    params.update(step_result)

    results = {}
    return results

  def choose_storage_path(params):
    params['view context'] = params['context']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['view context']
    step_params['key'] = 'app context'
    step_result = get_value(step_params)
    params['app context'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['app context']
    step_result = get_course_tracker_data_storage_path(step_params)
    params['storage path'] = step_result['storage path']

    step_params = {}
    step_params.update(params)
    step_params['initial path'] = params['storage path']
    step_result = show_open_file_dialog(step_params)
    params['storage path'] = step_result['path']
    params['is ok'] = step_result['is ok']

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['view context']
    step_params['param2'] = params['storage path']
    step_params['template'] = {'storage path': 'param2', 'view context': 'param1'}
    step_params['param3'] = None
    step_result = make_data(step_params)
    params['alt context'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['alt context']
    step_params['alternative_value'] = params['is ok']
    step_params['alternative_actions'] = [{'ACTION': 'set course tracker storage path', 'VALUE': True}]
    step_result = do_alternatively(step_params)

    results = {}
    return results

  def clone_data(params):

    step_params = {}
    step_params.update(params)
    step_params['kpiece'] = params['data']
    step_result = convert_to_yaml(step_params)
    params['yaml'] = step_result['yaml']

    step_params = {}
    step_params.update(params)
    step_params['yaml_content'] = params['yaml']
    step_result = load_yaml_in_python(step_params)
    params['data'] = step_result['result']

    results = {}
    results['data'] = params['data']
    return results

  def convert_date_to_date_with_weekday(params):
    params['weekdays'] = knowledge_get_or_literal('weekday short names')

    def EXEC1(weekdays, value, ):
      from datetime import date
      if type(value) is not date:
        converted_value = ''
      else:
        weekday = value.weekday()
        converted_value = '%s, %s' % (value, weekdays[weekday])
      return locals()
    step_result = EXEC1(params['weekdays'], params['value'], )
    params.update(step_result)

    results = {}
    results['converted_value'] = params['converted_value']
    return results

  def convert_schedule_to_string(params):
    params['weekdays'] = knowledge_get_or_literal('weekday short names')

    def EXEC1(weekdays, value, ):
      schedule = value
      schedule_string = ', '.join([weekdays[i] for i in sorted(schedule)])
      converted_value = schedule_string
      return locals()
    step_result = EXEC1(params['weekdays'], params['value'], )
    params.update(step_result)

    results = {}
    results['converted_value'] = params['converted_value']
    return results

  def convert_string_to_date(params):

    def EXEC1(value, ):
      from System import DateTime
      from datetime import date
      
      if not value:
        converted_value = None
      date_time = DateTime.Parse(value)
      converted_value = date(date_time.Year, date_time.Month, date_time.Day)
      return locals()
    step_result = EXEC1(params['value'], )
    params.update(step_result)

    results = {}
    results['converted_value'] = params['converted_value']
    return results

  def convert_string_to_datetime(params):

    def EXEC1(value, ):
      from System import DateTime
      from datetime import datetime
      
      if not value:
        converted_value = None
      else:
        date_time = DateTime.Parse(value)
        millis = date_time.Subtract(DateTime(date_time.Year, date_time.Month, date_time.Day, date_time.Hour, date_time.Minute, date_time.Second)).TotalMilliseconds
        micros = int(millis * 1000)
        converted_value = datetime(date_time.Year, date_time.Month, date_time.Day, date_time.Hour, date_time.Minute, date_time.Second, micros)
      return locals()
    step_result = EXEC1(params['value'], )
    params.update(step_result)

    results = {}
    results['converted_value'] = params['converted_value']
    return results

  def convert_string_to_schedule(params):
    params['weekdays'] = knowledge_get_or_literal('weekday short names')

    def EXEC1(weekdays, value, ):
      parts = [part.lower() for part in value.replace(',', ' ').split()]
      converted_value = [i for i in range(7) if weekdays[i] in parts]
      return locals()
    step_result = EXEC1(params['weekdays'], params['value'], )
    params.update(step_result)

    results = {}
    results['converted_value'] = params['converted_value']
    return results

  def convert_to_yaml(params):

    def EXEC1(kpiece, ):
      def to_yaml(kpiece):
        import yaml
        def represent_str(Dumper, data):
          style = '|' if ((type(data) is unicode and u'\n' in data) or (type(data) is str and '\n' in data)) else None
          return Dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style=style)
        yaml.add_representer(str, represent_str)
        yaml.add_representer(unicode, represent_str)
        class MyStream(object):
          def __init__(self):
            self.buf = []
          def write(self, data):
            self.buf.append(data)
          def getvalue(self):
            return ''.join(self.buf)
        stream = MyStream()
        yaml.dump(kpiece, stream = stream, default_style = None,
          default_flow_style=False, allow_unicode=True, encoding=None)
        return stream.getvalue()
      yaml = to_yaml(kpiece)
      return locals()
    step_result = EXEC1(params['kpiece'], )
    params.update(step_result)

    results = {}
    results['yaml'] = params['yaml']
    return results

  def create_data_from_definition(params):

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['definition']
    step_result = clone_data(step_params)
    params['data'] = step_result['data']

    results = {}
    results['data'] = params['data']
    return results

  def create_wpf_application(params):

    def EXEC1():
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import Application
      application = Application()
      def handle_exception(s, e):
        execute_knowledge_piece('write .net exception to log', {'exception': e.Exception})
        e.Handled = True
      application.DispatcherUnhandledException += handle_exception
      return locals()
    step_result = EXEC1()
    params.update(step_result)

    results = {}
    results['application'] = params['application']
    return results

  def create_wpf_binding(params):

    def EXEC1(attributes, ):
      def dummy(attributes):
       import clr
       clr.AddReferenceByPartialName('PresentationFramework')
       from System import Nullable
       from System.Windows import PropertyPath
       from System.Windows.Data import Binding
       from System.Windows.Data import BindingOperations
       from WebPythonHost import DelegateConverter
       from WebPythonHost import DelegatePropertyDescriptor
       from datetime import date
       from datetime import datetime
      
       def set_value(dict, key, value):
         dict[key] = value
      
       binding_name = attributes.get('binding')
       if not binding_name:
         return None
       binding_index = attributes.get('binding index')
       if binding_index is not None:
         #binding = Binding('.[%s][%d]' % (binding_name, binding_index))
         getter = lambda data: data[binding_name][binding_index]
         setter = lambda data, value: set_value(data[binding_name], binding_index, value)
         property_name = '%s[%d]' % (binding_name, binding_index)
       else:
         #binding = Binding('.[%s]' % binding_name)
         getter = lambda data: data[binding_name]
         setter = lambda data, value: set_value(data, binding_name, value)
         property_name = binding_name
       data_type_name = attributes.get('data type')
       data_type = None
       if data_type_name == 'integer':
         data_type = Nullable[int]
       elif data_type_name == 'date':
         data_type = date
       elif data_type_name == 'datetime':
         data_type = datetime
       property_descriptor = DelegatePropertyDescriptor(property_name, getter, setter, PropertyType_Setter = data_type)
       binding_path = PropertyPath('(0)', property_descriptor)
       converter = None
       converter_name = attributes.get('data converter')
       if converter_name:
         converter_def = knowledge_get(converter_name)
         if converter_def:
           forward_converter_name = converter_def['convert']
           back_converter_name = converter_def.get('convert back')
           forward_converter = (lambda value: execute_knowledge_piece(forward_converter_name, {'value': value})['converted_value']) if forward_converter_name else None
           back_converter = (lambda value: execute_knowledge_piece(back_converter_name, {'value': value})['converted_value']) if back_converter_name else None
           converter = DelegateConverter(forward_converter, back_converter)
       elif data_type_name == 'date':
         converter = DelegateConverter(lambda value: str(value) if value else '', lambda value: execute_knowledge_piece('convert string to date', {'value': value})['converted_value'])
       elif data_type_name == 'datetime':
         converter = DelegateConverter(lambda value: str(value) if value else '', lambda value: execute_knowledge_piece('convert string to datetime', {'value': value})['converted_value'])
       return Binding(Path = binding_path, Converter = converter, TargetNullValue = '')
      binding = dummy(attributes)
      return locals()
    step_result = EXEC1(params['binding attributes'], )
    params['wpf binding'] = step_result['binding']

    results = {}
    results['wpf binding'] = params['wpf binding']
    return results

  def create_wpf_element_for_column(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      clr.AddReferenceByPartialName('WPFToolkit')
      #from System.Windows.Controls import DataGridTextColumn
      from Microsoft.Windows.Controls import DataGridTextColumn
      from System.Windows.Controls import TextBlock
      
      element = DataGridTextColumn(Header = TextBlock(Text = view['attributes']['header']))
      binding = execute_knowledge_piece('create wpf binding', {'binding attributes': view['attributes']})['wpf binding']
      if binding:
        element.Binding = binding
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']

    results = {}
    results['wpf element'] = params['wpf element']
    return results

  def create_wpf_element_for_command(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows.Controls import Button
      from System.Windows.Controls import TextBlock
      
      element = Button(Content = TextBlock(Text = view['attributes']['name']))
      command = view['attributes'].get('command')
      if command:
        parameter_source_name = view['attributes'].get('parameter source')
        element.Click += lambda sender, e: execute_knowledge_piece('execute command wpf', {
          'context': context,
          'command': command,
          'data context': element.DataContext,
          'parameter source name': parameter_source_name,
          'wpf element': element,
          'view attributes': view['attributes'],
        })
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']

    results = {}
    results['wpf element'] = params['wpf element']
    return results

  def create_wpf_element_for_data_field(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import Thickness
      from System.Windows.Controls import StackPanel
      from System.Windows.Controls import TextBlock
      from System.Windows.Controls import TextBox
      from System.Windows.Data import BindingOperations
      
      element = StackPanel(Margin = Thickness(10,5,10,5))
      element.Children.Add(TextBlock(Text = view['attributes'].get('header')))
      binding = execute_knowledge_piece('create wpf binding', {'binding attributes': view['attributes']})['wpf binding']
      textbox = TextBox()
      textbox.IsReadOnly = bool(view['attributes'].get('read only'))
      if binding:
        BindingOperations.SetBinding(textbox, TextBox.TextProperty, binding)
      element.Children.Add(textbox)
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']

    results = {}
    results['wpf element'] = params['wpf element']
    return results

  def create_wpf_element_for_dock_panel(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import Thickness
      from System.Windows.Controls import Dock
      from System.Windows.Controls import DockPanel
      
      element = DockPanel(Margin = Thickness(10,5,10,5))
      def add_children(child_elements):
        for child_element, child in child_elements:
          #DockPanel.SetDock(child_element, Dock.Top)
          element.Children.Add(child_element)
      linkers = {
        'children': lambda parent, child_elements: add_children(child_elements),
      }
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def create_wpf_element_for_horizontal_grid(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import HorizontalAlignment
      from System.Windows import GridLength
      from System.Windows import VerticalAlignment
      from System.Windows.Controls import ColumnDefinition
      from System.Windows.Controls import Grid
      from System.Windows.Controls import GridSplitter
      
      element = Grid()
      def add_children(child_elements):
        for child_element, child in child_elements:
          if element.Children.Count > 0:
            splitter = GridSplitter(VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Center, Width = 3)
            Grid.SetColumn(splitter, element.Children.Count)
            element.ColumnDefinitions.Add(ColumnDefinition(Width = GridLength.Auto))
            element.Children.Add(splitter)
          Grid.SetColumn(child_element, element.Children.Count)
          element.ColumnDefinitions.Add(ColumnDefinition())
          element.Children.Add(child_element)
      linkers = {
        'children': lambda parent, child_elements: add_children(child_elements),
      }
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def create_wpf_element_for_list(params):

    def EXEC1(context, view, ):
      def dummy(context, view):
        import clr
        clr.AddReferenceByPartialName('PresentationFramework')
        clr.AddReferenceByPartialName('WPFToolkit')
        from System.Windows import EventSetter
        from System.Windows import HorizontalAlignment
        from System.Windows import Setter
        from System.Windows import Style
        from System.Windows import Thickness
        from System.Windows import VerticalAlignment
        #from System.Windows.Controls import DataGrid
        #from System.Windows.Controls import DataGridCell
        #from System.Windows.Controls import DataGridSelectionUnit
        from Microsoft.Windows.Controls import DataGrid
        from Microsoft.Windows.Controls import DataGridCell
        from Microsoft.Windows.Controls import DataGridSelectionUnit
        from System.Windows.Controls import Dock
        from System.Windows.Controls import DockPanel
        from System.Windows.Controls import Grid
        from System.Windows.Controls import TextBlock
        from System.Windows.Controls import UserControl
        from System.Windows.Controls import WrapPanel
        from System.Windows.Data import BindingOperations
        from System.Windows.Input import MouseButtonEventHandler
        from System.ComponentModel import ListSortDirection
      
        class MyDataGrid(UserControl):
          def __init__(self, view):
            self.commands = []
            self.default_command = None
      
            grid = Grid(HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top)
            dockPanel = DockPanel()
            grid.Children.Add(dockPanel)
            header = view['attributes'].get('header')
            if header:
              headerTextBlock = TextBlock(Text = header, Margin = Thickness(2,2,2,2))
              DockPanel.SetDock(headerTextBlock, Dock.Top)
              dockPanel.Children.Add(headerTextBlock)
            dataGrid = DataGrid()
            dockPanel.Children.Add(dataGrid)
            dataGrid.CanUserAddRows = False
            dataGrid.CanUserResizeRows = False
            dataGrid.CanUserSortColumns = True
            dataGrid.SelectionUnit = DataGridSelectionUnit.CellOrRowHeader
            buttonPanel = WrapPanel()
            DockPanel.SetDock(buttonPanel, Dock.Bottom)
            dockPanel.Children.Insert(0, buttonPanel)
            cellStyle = Style(TargetType = DataGridCell)
            cellStyle.Setters.Add(EventSetter(Event = DataGridCell.MouseDoubleClickEvent, Handler = MouseButtonEventHandler(lambda sender, e: element.on_double_click(sender, e))))
            dataGrid.CellStyle = cellStyle
            dataGrid.Sorting += self.on_sorting
            self.dataGrid = dataGrid
            self.buttonPanel = buttonPanel
            self.Content = grid
            self.ItemsBinding = None
          def get_DataGrid(self):
            return self.dataGrid
          def add_command(self, command_element):
            self.buttonPanel.Children.Add(command_element)
          def on_sorting(self, sender, e):
            prevSortDir = e.Column.SortDirection
            newSortDir = ListSortDirection.Descending if prevSortDir == ListSortDirection.Ascending else (ListSortDirection.Ascending if prevSortDir is None else None)
            if newSortDir is not None:
              binding = e.Column.Binding
              path = binding.Path
              propDesc = path.PathParameters[0]
              getter = propDesc.ValueGetter
              items = list(sorted(self.dataGrid.ItemsSource, key = lambda item: getter(item)))
              if newSortDir == ListSortDirection.Descending:
                items.reverse()
              self.dataGrid.ItemsSource = items
            else:
              BindingOperations.SetBinding(self.dataGrid, DataGrid.ItemsSourceProperty, self.ItemsBinding)
            e.Column.SortDirection = newSortDir
            e.Handled = True
          def on_double_click(self, sender, e):
            if self.default_command:
              self.default_command(sender, e)
          def get_selected_item(self):
            #return self.get_DataGrid().SelectedItem
            cells = self.get_DataGrid().SelectedCells
            cell = cells.Count > 0 and cells[0]
            return cell and cell.Item
          def get_selected_items(self):
            cells = self.get_DataGrid().SelectedCells
            distinct_ids = set()
            items = []
            for cell in cells:
              item = cell.Item
              item_id = id(item)
              if item_id not in distinct_ids:
                items.append(item)
                distinct_ids.add(item_id)
            return items
      
        element = MyDataGrid(view)
        dataGrid = element.get_DataGrid()
        dataGrid.IsReadOnly = bool(view['attributes'].get('read only'))
        binding = execute_knowledge_piece('create wpf binding', {'binding attributes': view['attributes']})['wpf binding']
        if binding:
          element.ItemsBinding = binding
          BindingOperations.SetBinding(dataGrid, DataGrid.ItemsSourceProperty, binding)
        def add_columns(child_elements):
          for child_element, child in child_elements:
            dataGrid.Columns.Add(child_element)
        def add_commands(child_elements):
          for child_element, child in child_elements:
            element.add_command(child_element)
            #write_to_log(to_html(to_yaml(child)))
            if child['attributes'].get('is default'):
              command_attributes = child['attributes']
              command = command_attributes.get('command')
              parameter_source_name = command_attributes.get('parameter source')
              element.default_command = lambda sender, e: execute_knowledge_piece('execute command wpf', {
                'context': context,
                'command': command,
                'data context': element.DataContext,
                'parameter source name': parameter_source_name,
                'wpf element': element,
                'view attributes': command_attributes,
              })
        linkers = {
          'columns': lambda parent, child_elements: add_columns(child_elements),
          'commands': lambda parent, child_elements: add_commands(child_elements),
        }
        return (element, linkers)
      element, linkers = dummy(context, view)
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def create_wpf_element_for_menu(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows.Controls import Menu
      
      element = Menu()
      
      def add_children(child_elements):
        for child_element, child in child_elements:
          element.Items.Add(child_element)
      linkers = {
        'items': lambda parent, child_elements: add_children(child_elements),
      }
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def create_wpf_element_for_menu_item(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows.Controls import MenuItem
      from System.Windows.Controls import TextBlock
      
      header = view['attributes']['header']
      element = MenuItem(Header = TextBlock(Text = header))
      command = view['attributes'].get('command')
      if command:
        parameter_source_name = view['attributes'].get('parameter source')
        element.Click += lambda sender, e: execute_knowledge_piece('execute command wpf', {
          'context': context,
          'command': command,
          'data context': element.DataContext,
          'parameter source name': parameter_source_name,
          'wpf element': element,
          'view attributes': view['attributes'],
        })
      
      def add_children(child_elements):
        for child_element, child in child_elements:
          element.Items.Add(child_element)
      linkers = {
        'items': lambda parent, child_elements: add_children(child_elements),
      }
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def create_wpf_element_for_unknown(params):

    def EXEC1(view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows.Controls import TextBlock
      
      element = TextBlock(Text = 'Неизвестный тип элемента: ' + view['kind'])
      return locals()
    step_result = EXEC1(params['view'], )
    params['wpf element'] = step_result['element']

    results = {}
    results['wpf element'] = params['wpf element']
    return results

  def create_wpf_element_for_vertical_grid(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import HorizontalAlignment
      from System.Windows import GridLength
      from System.Windows import VerticalAlignment
      from System.Windows.Controls import Grid
      from System.Windows.Controls import GridSplitter
      from System.Windows.Controls import RowDefinition
      
      element = Grid()
      def add_children(child_elements):
        for child_element, child in child_elements:
          if element.Children.Count > 0:
            splitter = GridSplitter(VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Height = 3)
            Grid.SetRow(splitter, element.Children.Count)
            element.RowDefinitions.Add(RowDefinition(Height = GridLength.Auto))
            element.Children.Add(splitter)
          Grid.SetRow(child_element, element.Children.Count)
          element.RowDefinitions.Add(RowDefinition())
          element.Children.Add(child_element)
      linkers = {
        'children': lambda parent, child_elements: add_children(child_elements),
      }
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def create_wpf_element_for_wrap_panel(params):

    def EXEC1(context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import Thickness
      from System.Windows.Controls import WrapPanel
      
      element = WrapPanel(Margin = Thickness(10,5,10,5))
      def add_children(child_elements):
        for child_element, child in child_elements:
          element.Children.Add(child_element)
      linkers = {
        'children': lambda parent, child_elements: add_children(child_elements),
      }
      return locals()
    step_result = EXEC1(params['context'], params['view'], )
    params['wpf element'] = step_result['element']
    params['child linkers'] = step_result['linkers']

    results = {}
    results['wpf element'] = params['wpf element']
    results['child linkers'] = params['child linkers']
    return results

  def default_if_None(params):
    params['default_value'] = params['default value']

    def EXEC1(default_value, value, ):
      value = value if value is not None else default_value
      return locals()
    step_result = EXEC1(params['default_value'], params['value'], )
    params.update(step_result)

    results = {}
    results['value'] = params['value']
    return results

  def delete_addition(params):

    def EXEC1(selected_data, data, ):
      data['additions'].remove(selected_data)
      return locals()
    step_result = EXEC1(params['selected data'], params['data'], )
    params.update(step_result)

    results = {}
    return results

  def delete_cancellation(params):

    def EXEC1(selected_data, data, ):
      data['cancellations'].remove(selected_data)
      return locals()
    step_result = EXEC1(params['selected data'], params['data'], )
    params.update(step_result)

    results = {}
    return results

  def delete_from_list(params):
    params['key_value'] = params['key value']

    def EXEC1(key_value, list, key, ):
      index = -1
      for i in range(len(list)):
        item = list[i]
        if key in item and item[key] == key_value:
          index = i
          break
      if index >= 0:
        del list[index]
      return locals()
    step_result = EXEC1(params['key_value'], params['list'], params['key'], )
    params.update(step_result)

    results = {}
    return results

  def delete_selected_course(params):

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['selected data']
    step_result = clone_data(step_params)
    params['course data'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course data']
    step_params['key'] = 'deleted'
    step_params['value'] = True
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['data'] = params['course data']
    step_result = save_course_data(step_params)

    results = {}
    return results

  def do_alternatively(params):

    def EXEC1(alternative_value, context, alternative_actions, ):
      results = {}
      for alternative_action in alternative_actions:
        value = alternative_action['VALUE']
        if value == alternative_value:
          action_alias = alternative_action['ACTION']
          parameters = {
            'context': context,
          }
          if type(context) is dict:
            parameters.update(context)
          results = execute_knowledge_piece(action_alias, parameters)
          break
      return locals()
    step_result = EXEC1(params['alternative_value'], params['context'], params['alternative_actions'], )
    params.update(step_result)

    results = {}
    results['results'] = params['results']
    return results

  def execute_command_wpf(params):
    params['data_context'] = params['data context']
    params['parameter_source_name'] = params['parameter source name']
    params['element'] = params['wpf element']
    params['view_attrbutes'] = params['view attributes']

    def EXEC1(data_context, element, command, context, parameter_source_name, view_attrbutes, ):
      try:
        #parameter_source = element.FindName(parameter_source_name)
        parameter_source = parameter_source_name and context.get('name scope', {}).get(parameter_source_name)
        selected_data = parameter_source and execute_knowledge_piece('get selected data from list', {'data source': parameter_source})['selected data']
        handled = False
        if parameter_source_name and not selected_data:
          on_selection_empty = view_attrbutes.get('on selection empty')
          if on_selection_empty:
            execute_knowledge_piece('execute command wpf', {
              'context': context,
              'command': on_selection_empty['command'],
              'data context': data_context,
              'parameter source name': on_selection_empty.get('parameter source'),
              'wpf element': element,
              'view attributes': on_selection_empty,
            })
          handled = True
        if not handled:
          selected_items = parameter_source and parameter_source.get_selected_items()
          execute_knowledge_piece(command, {
            'context': context,
            'data': data_context,
            'parameter_source': parameter_source,
            'selected data': selected_data,
            'selected items': selected_items})
          if view_attrbutes.get('type') == 'submit':
            context['window'].Close()
            parent_view_context = context.get('parent view context')
            if parent_view_context:
              refresh = parent_view_context['refresh']
              refresh(parent_view_context)
          elif not view_attrbutes.get('no refresh'):
            #write_to_log('<br/><br/><b>%s</b><br/><br/>' % to_html(repr(context)))
            refresh = context['refresh']
            refresh(context)
      except:
        execute_knowledge_piece('write python exception to log', {})
      return locals()
    step_result = EXEC1(params['data_context'], params['element'], params['command'], params['context'], params['parameter_source_name'], params['view_attrbutes'], )
    params.update(step_result)

    results = {}
    return results

  def _execute_knowledge_piece(params):

    def EXEC1(knowledge_piece_parameters, knowledge_piece_alias, ):
      def execute_knowledge_piece_EXEC(knowledge_piece_alias, knowledge_piece_parameters):
        if is_debug:
          write_to_log('<div><b>%s</b></div>' % knowledge_piece_alias)
      
        knowledge_piece = knowledge_get(knowledge_piece_alias)
        if not knowledge_piece:
          raise Exception('"%s" not found' % knowledge_piece_alias)
      
        def get_params(param_defs, knowledge_piece_parameters):
          params = {}
          for p in param_defs:
            if type(p) is dict and 'AS' in p:
              as_ = p['AS']
              if 'LITERAL' in p:
                params[as_] = p['LITERAL']
              elif 'KNOWLEDGE' in p:
                params[as_] = knowledge_get(p['KNOWLEDGE'])
              elif 'PARAM' in p:
                params[as_] = knowledge_piece_parameters.get(p['PARAM'])
              elif 'WHAT' in p: # legacy
                what = p["WHAT"]
                if what in knowledge_piece_parameters:
                  value = knowledge_piece_parameters.get(what)
                else:
                  value = knowledge_get(what)
                if value is None:
                  value = what
                params[as_] = value
            elif type(p) is dict and len(p) == 1:
              pair = p.items()[0]
              params[pair[0]] = knowledge_piece_parameters[pair[1]]
            elif type(p) is str or type(p) is unicode:
              params[p] = knowledge_piece_parameters[p]
            else:
              raise Exception('unrecognized step param: %s' % repr(p))
          return params
      
        parameters = get_params(knowledge_piece.get('TAKES', []), knowledge_piece_parameters)
      
        if is_debug:
          write_to_log(u'<div>Входные параметры: <pre>%s</pre></div><ul>' % html_encode(to_yaml(parameters)))
      
        steps = knowledge_piece["STEPS"]
      
        def process_step(step, parameters):
          if is_debug:
            write_to_log(u'<li><div>Вызов шага: <pre>%s</pre></div>' % html_encode(to_yaml(step)))
          exec_code = None
          step_conditions = None
          if type(step) is dict and len(step) > 0:
            if 'EXEC' not in step:
              step_pair = step.items()[0]
              alias = step_pair[0]
              step_conditions = step_pair[1]
            else:
              alias = 'EXEC'
              exec_code = step.get('EXEC')
              step_conditions = step
          else:
            alias = step
          step_parameters = {}
          if type(step_conditions) is dict:
            if alias == 'EXEC' and 'TAKES' not in step_conditions:
              step_parameters = parameters
            else:
              step_parameters = get_params(step_conditions.get('TAKES', []), parameters)
          if is_debug:
            write_to_log(u'<div>Входные параметры шага: <pre>%s</pre></div>' % html_encode(to_yaml(step_parameters)))
          if alias == 'EXEC':
            code = exec_code
            exec code in globals(), step_parameters
            step_results = step_parameters
          else:
            step_results = execute_knowledge_piece(alias, step_parameters)
          if is_debug:
            write_to_log(u'<div>Все результаты шага %s: <pre>%s</pre></div>' % (alias, html_encode(to_yaml(step_results))))
          if type(step_conditions) is dict:
            if alias == 'EXEC' and 'RESULT' not in step_conditions:
              step_results = step_results
            else:
              step_results = get_params(step_conditions.get('RESULT', []), step_results)
          if is_debug:
            write_to_log(u'<div>Выбранные результаты шага %s: <pre>%s</pre></div></li>' % (alias, html_encode(to_yaml(step_results))))
          parameters.update(step_results)
          if is_debug:
            write_to_log(u'<div>Внутренние параметры после шага %s: <pre>%s</pre></div>' % (alias, html_encode(to_yaml(parameters))))
      
        for step in steps:
          process_step(step, parameters)
      
        #if type(knowledge_piece_parameters) is dict:
        #  knowledge_piece_parameters.update(results)
      
        results = get_params(knowledge_piece.get('RESULT', []), parameters)
        if is_debug:
          write_to_log(u'</ul><div>Выбранные результаты %s: <pre>%s</pre></div>' % (knowledge_piece_alias, html_encode(to_yaml(results))))
        return results
      results = execute_knowledge_piece_EXEC(knowledge_piece_alias, knowledge_piece_parameters)
      return locals()
    step_result = EXEC1(params['knowledge_piece_parameters'], params['knowledge_piece_alias'], )
    params.update(step_result)

    results = {}
    results['results'] = params['results']
    return results

  def get_change_list(params):

    def EXEC1(start, end, data, history, ):
      if len(history) < end - start:
        change_list = [data]
      else:
        change_list = history[len(history) - (end - start):len(history)]
      return locals()
    step_result = EXEC1(params['start'], params['end'], params['data'], params['history'], )
    params['change list'] = step_result['change_list']

    results = {}
    results['change list'] = params['change list']
    return results

  def get_changes(params):

    def EXEC1(data, prev_data, ):
      if type(data) is dict:
        if type(prev_data) is not dict:
          changes = data
        else:
          changes = {}
          prev_keys = set(prev_data.iterkeys())
          for key, value in data.iteritems():
            if key not in prev_keys:
              changes[key] = value
            else:
              prev_keys.remove(key)
              item_changes = execute_knowledge_piece('get changes', {'data': value, 'previous data': prev_data[key]})['changes']
              if item_changes:
                changes[key] = item_changes
          for key in prev_keys:
            changes[key] = None
      elif type(data) is list:
        if type(prev_data) is not list:
          changes = data
        else:
          changes = []
          prev_items_with_id = dict([(item['id'], item) for item in prev_data if type(item) is dict and 'id' in item])
          for item in data:
            if type(item) is dict and 'id' in item:
              id = item['id']
              prev_item = prev_items_with_id.pop(id, None)
              if prev_item is not None:
                item_changes = execute_knowledge_piece('get changes', {'data': item, 'previous data': prev_item})['changes']
                if item_changes:
                  item_changes['id'] = id
                  changes.append(item_changes)
              else:
                changes.append(item)
            else:
              changes.append(item)
          for id, item in prev_items_with_id.iteritems():
            changes.append({'id': id, 'deleted': True})
      else:
        if data != prev_data:
          changes = data
        else:
          changes = None
      return locals()
    step_result = EXEC1(params['data'], params['previous data'], )
    params['changes'] = step_result['changes']

    results = {}
    results['changes'] = params['changes']
    return results

  def get_course_tracker_courses(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'data'
    step_result = get_value(step_params)
    params['response'] = step_result['value']

    results = {}
    results['response'] = params['response']
    return results

  def get_course_tracker_data_change_history_path(params):

    def EXEC1(path, ):
      from System.IO import Path
      hist_path = Path.ChangeExtension(path, 'history.yaml')
      return locals()
    step_result = EXEC1(params['storage path'], )
    params['history path'] = step_result['hist_path']

    results = {}
    results['history path'] = params['history path']
    return results

  def get_course_tracker_data_storage_path(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['settings', 'storage path']
    step_result = get_value(step_params)
    params['storage path'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['value'] = params['storage path']
    step_params['default value'] = 'data/courses.yaml'
    step_result = default_if_None(step_params)
    params['storage path'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['storage path']
    step_result = map_path_relative_to_application(step_params)
    params['storage path'] = step_result['path']

    results = {}
    results['storage path'] = params['storage path']
    return results

  def get_current_time(params):

    def EXEC1():
      from datetime import datetime
      current_time = datetime.utcnow()
      return locals()
    step_result = EXEC1()
    params['current time'] = step_result['current_time']

    results = {}
    results['current time'] = params['current time']
    return results

  def get_item_by_id(params):

    def EXEC1(id_name, id, list, ):
      item = None
      for it in list:
        if it.get(id_name) == id:
          item = it
          break
      return locals()
    step_result = EXEC1(params['id definition'], params['id value'], params['list'], )
    params['item'] = step_result['item']

    results = {}
    results['item'] = params['item']
    return results

  def get_length(params):

    def EXEC1(collection, ):
      length = len(collection)
      return locals()
    step_result = EXEC1(params['collection'], )
    params.update(step_result)

    results = {}
    results['length'] = params['length']
    return results

  def get_selected_data_from_list(params):
    params['data_source'] = params['data source']

    def EXEC1(data_source, ):
      data = data_source.get_selected_item() # hack: using internal knowledge
      return locals()
    step_result = EXEC1(params['data_source'], )
    params.update(step_result)

    results = {}
    results['selected data'] = params['data']
    return results

  def get_value(params):

    def EXEC1(key, dictionary, ):
      if type(key) is not list:
        key = [key]
      value = dictionary
      for key_part in key:
        if type(value) is dict:
          value = value.get(key_part, None)
        elif value is not None:
          value = value[key_part]
      return locals()
    step_result = EXEC1(params['key'], params['dictionary'], )
    params.update(step_result)

    results = {}
    results['value'] = params['value']
    return results

  def get_yaml_data_path(params):

    def EXEC1(data_name, ):
      from WebPythonHost import ApplicationHlp
      from System.IO import Path
      dir = ApplicationHlp.MapPath('data')
      data_path = Path.Combine(dir, data_name + '.yaml')
      return locals()
    step_result = EXEC1(params['data_name'], )
    params.update(step_result)

    results = {}
    results['data_path'] = params['data_path']
    return results

  def handle_course_tracker_server_request(params):

    step_params = {}
    step_params.update(params)
    step_params['yaml_content'] = params['request text']
    step_result = load_yaml_in_python(step_params)
    params['request'] = step_result['result']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['request']
    step_params['key'] = 'command'
    step_result = get_value(step_params)
    params['command'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['context']
    step_params['param2'] = params['request']
    step_params['template'] = {'request': 'param2', 'context': 'param1'}
    step_params['param3'] = None
    step_result = make_data(step_params)
    params['parameters'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['parameters']
    step_params['alternative_value'] = params['command']
    step_params['alternative_actions'] = [{'ACTION': 'get course tracker courses', 'VALUE': 'get courses'}, {'ACTION': 'handle sync course tracker changes request', 'VALUE': 'sync changes'}, {'ACTION': 'get course tracker courses', 'VALUE': None}]
    step_result = do_alternatively(step_params)
    params['results'] = step_result['results']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['results']
    step_params['key'] = 'response'
    step_result = get_value(step_params)
    params['response'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['kpiece'] = params['response']
    step_result = convert_to_yaml(step_params)
    params['response text'] = step_result['yaml']

    results = {}
    results['response text'] = params['response text']
    return results

  def handle_sync_course_tracker_changes_request(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['request']
    step_params['key'] = ['data', 'change list']
    step_result = get_value(step_params)
    params['change list'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['request']
    step_params['key'] = ['data', 'last change number']
    step_result = get_value(step_params)
    params['last change number'] = step_result['value']

    def EXEC1(context, change_list, last_change_number, ):
      from System.Threading import Monitor
      Monitor.Enter(context)
      try:
        results = execute_knowledge_piece('sync course tracker changes', {
          'context': context,
          'change list': change_list,
          'last change number': last_change_number,
        })
        change_list = results['change list']
        last_change_number = results['last change number']
      finally:
        Monitor.Exit(context)
      return locals()
    step_result = EXEC1(params['context'], params['change list'], params['last change number'], )
    params['change list'] = step_result['change_list']
    params['last change number'] = step_result['last_change_number']

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['change list']
    step_params['param2'] = params['last change number']
    step_params['template'] = {'last change number': 'param2', 'change list': 'param1'}
    step_params['param3'] = None
    step_result = make_data(step_params)
    params['response'] = step_result['data']

    results = {}
    results['response'] = params['response']
    return results

  def increment(params):

    def EXEC1(value, ):
      value = value + 1
      return locals()
    step_result = EXEC1(params['value'], )
    params.update(step_result)

    results = {}
    results['value'] = params['value']
    return results

  def load__net_host_settings(params):

    def EXEC1():
      import clr
      #clr.AddReferenceByPartialName('WebPythonHost')
      from WebPythonHost import ApplicationHlp
      path = ApplicationHlp.MapPath('Settings.config')
      
      clr.AddReferenceByPartialName('System.Xml.Linq')
      from System.Xml.Linq import XElement
      xElement = XElement.Load(path)
      settings = dict([(child.Name.LocalName, child.Value) for child in xElement.Elements()])
      return locals()
    step_result = EXEC1()
    params.update(step_result)

    results = {}
    results['settings'] = params['settings']
    return results

  def load_course_tracker_data(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['settings', 'is networking']
    step_result = get_value(step_params)
    params['is networking'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['alternative_value'] = params['is networking']
    step_params['alternative_actions'] = [{'ACTION': 'load course tracker data from server', 'VALUE': True}, {'ACTION': 'load course tracker data from file', 'VALUE': False}, {'ACTION': 'load course tracker data from file', 'VALUE': None}]
    step_result = do_alternatively(step_params)
    params['results'] = step_result['results']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['results']
    step_params['key'] = 'course tracker data'
    step_result = get_value(step_params)
    params['course tracker data'] = step_result['value']

    results = {}
    results['course tracker data'] = params['course tracker data']
    return results

  def load_course_tracker_data_from_file(params):

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = get_course_tracker_data_storage_path(step_params)
    params['storage path'] = step_result['storage path']

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['storage path']
    step_result = load_yaml_data_from_file(step_params)
    params['course tracker data'] = step_result['data']

    results = {}
    results['course tracker data'] = params['course tracker data']
    return results

  def load_course_tracker_data_from_server(params):

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['request'] = {'command': 'get courses'}
    step_result = send_course_tracker_request_to_server(step_params)
    params['course tracker data'] = step_result['response']

    results = {}
    results['course tracker data'] = params['course tracker data']
    return results

  def load_course_tracker_settings(params):

    step_params = {}
    step_params.update(params)
    step_params['path'] = 'settings.yaml'
    step_result = map_path_relative_to_application(step_params)
    params['path'] = step_result['path']

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['path']
    step_result = load_yaml_data_from_file(step_params)
    params['settings'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['value'] = params['settings']
    step_params['default value'] = {'storage path': 'data/courses.yaml'}
    step_result = default_if_None(step_params)
    params['settings'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['value'] = params['settings']
    step_params['key'] = 'settings'
    step_result = set_value(step_params)

    results = {}
    results['settings'] = params['settings']
    return results

  def load_data_by_name(params):

    step_params = {}
    step_params.update(params)
    step_params['data_name'] = params['data_name']
    step_result = get_yaml_data_path(step_params)
    params['data_path'] = step_result['data_path']

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['data_path']
    step_result = load_yaml_data_from_file(step_params)
    params['data'] = step_result['data']

    results = {}
    results['data'] = params['data']
    return results

  def load_yaml_data_from_file(params):

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['path']
    step_result = read_file_text(step_params)
    params['text'] = step_result['text']

    step_params = {}
    step_params.update(params)
    step_params['yaml_content'] = params['text']
    step_result = load_yaml_in_python(step_params)
    params['data'] = step_result['result']

    results = {}
    results['data'] = params['data']
    return results

  def load_yaml_in_python(params):

    def EXEC1(yaml_content, ):
      if yaml_content is None:
        result = None
      else:
        import yaml
        result = yaml.load(yaml_content)
      return locals()
    step_result = EXEC1(params['yaml_content'], )
    params.update(step_result)

    results = {}
    results['result'] = params['result']
    return results

  def make_data(params):

    def EXEC1(param3, param1, template, param2, ):
      params = {
        'param1': param1,
        'param2': param2,
        'param3': param3,
      }
      def dummy(template, params):
        make_data = lambda template: execute_knowledge_piece('make data', dict(params.items() + {'template': template}.items()))['data']
        if type(template) is dict:
          data = dict((item[0], make_data(item[1])) for item in template.iteritems())
        elif type(template) is list:
          data = [make_data(item) for item in template]
        else:
          data = params.get(template, template)
        return data
      data = dummy(template, params)
      return locals()
    step_result = EXEC1(params['param3'], params['param1'], params['template'], params['param2'], )
    params.update(step_result)

    results = {}
    results['data'] = params['data']
    return results

  def make_wpf_element_from_view(params):
    params['view_definition'] = knowledge_get('view definition')

    def EXEC1(view_definition, context, view, ):
      def dummy(view, context):
        def process_links(context, view, element, linkers):
          links = view.get('links', [])
          if type(links) is dict:
            links = [{'kind': kind, 'elements': elements} for kind, elements in links.iteritems()]
          for link in links:
            linker = linkers.get(link['kind'], None)
            if linker:
              childs = link.get('elements', [])
              child_elements = []
              for child in childs:
                child_element = execute_knowledge_piece('make wpf element from view', {'context': context, 'view': child})['element']
                child_elements.append((child_element, child))
              linker(element, child_elements)
      
        view_kind = view['kind']
        if view_kind not in view_definition['kinds']:
          view_kind = 'unknown'
        result = execute_knowledge_piece('create wpf element for ' + view_kind, {'context': context, 'view': view})
        element = result['wpf element']
        linkers = result.get('child linkers')
      
        attributes = view.get('attributes')
        ref_name = attributes and attributes.get('ref name')
        if ref_name:
          name_scope = context.setdefault('name scope', {})
          name_scope[ref_name] = element
          element.Name = ref_name.replace(' ', '_')
          #element.RegisterName(ref_name, element)
      
        execute_knowledge_piece('apply common attributes to wpf element', {'wpf element': element, 'attributes': attributes})
      
        process_links(context, view, element, linkers if linkers is not None else {})
      
        return element
      element = dummy(view, context)
      return locals()
    step_result = EXEC1(params['view_definition'], params['context'], params['view'], )
    params.update(step_result)

    results = {}
    results['element'] = params['element']
    return results

  def map_path_relative_to_application(params):

    def EXEC1(path, ):
      from System.IO import Path
      from WebPythonHost import ApplicationHlp
      if not Path.IsPathRooted(path):
        path = ApplicationHlp.MapPath(path)
      return locals()
    step_result = EXEC1(params['path'], )
    params.update(step_result)

    results = {}
    results['path'] = params['path']
    return results

  def open_course_details(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'app context'
    step_result = get_value(step_params)
    params['app context'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['selected data']
    step_result = clone_data(step_params)
    params['data'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['data']
    step_result = calculate_course_schedule_data(step_params)
    params['data'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['app context']
    step_params['data'] = params['data']
    step_params['parent context'] = params['context']
    step_params['view'] = knowledge_get('course details view')
    step_params['title'] = 'Course Details'
    step_result = open_view(step_params)

    results = {}
    return results

  def open_view(params):
    params['parent_context'] = params['parent context']

    def EXEC1(parent_context, title, data, context, view, ):
      import clr
      clr.AddReferenceByPartialName('PresentationCore')
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.Windows import SizeToContent
      from System.Windows import Window
      from System.Windows.Controls import ScrollViewer
      from System.Windows.Controls import ScrollBarVisibility
      window = Window()
      window.Title = title
      view_attributes = view.get('attributes', {})
      view_width = view_attributes.pop('width', None)
      view_height = view_attributes.pop('height', None)
      if view_width and view_height:
        window.Width = view_width
        window.Height = view_height
      elif view_width:
        window.Width = view_width
        window.SizeToContent = SizeToContent.Height
      elif view_height:
        window.Height = view_height
        window.SizeToContent = SizeToContent.Width
      else:
        window.SizeToContent = SizeToContent.WidthAndHeight
      #window.Content = ScrollViewer(VerticalScrollBarVisibility = ScrollBarVisibility.Auto)
      def refresh(view_context):
        view_context['window'].DataContext = view_context['data']
        view_context['window'].Content = execute_knowledge_piece('make wpf element from view', {'view': view_context['view'], 'context': view_context})['element']
      view_context = {'app context': context, 'window': window, 'data': data, 'view': view, 'refresh': refresh, 'parent view context': parent_context}
      refresh(view_context)
      window.Show()
      return locals()
    step_result = EXEC1(params['parent_context'], params['title'], params['data'], params['context'], params['view'], )
    params.update(step_result)

    results = {}
    results['window'] = params['window']
    return results

  def read_file_text(params):

    def EXEC1(path, ):
      from System.IO import File
      if File.Exists(path):
        text = File.ReadAllText(path)
      else:
        text = None
      return locals()
    step_result = EXEC1(params['path'], )
    params.update(step_result)

    results = {}
    results['text'] = params['text']
    return results

  def reload_course_tracker_data(params):

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = load_course_tracker_data(step_params)
    params['course tracker data'] = step_result['course tracker data']

    step_params = {}
    step_params.update(params)
    step_params['value'] = params['course tracker data']
    step_params['default value'] = {'courses': [], 'next course id': 1, 'courses history': []}
    step_result = default_if_None(step_params)
    params['course tracker data'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['value'] = params['course tracker data']
    step_params['key'] = 'data'
    step_result = set_value(step_params)

    results = {}
    results['course tracker data'] = params['course tracker data']
    return results

  def run_application(params):

    def EXEC1(application, window, ):
      if window:
        application.Run(window)
      else:
        application.Run()
      return locals()
    step_result = EXEC1(params['application'], params['window'], )
    params.update(step_result)

    results = {}
    return results

  def run_course_tracker(params):

    step_params = {}
    step_params.update(params)
    step_params['definition'] = knowledge_get('course tracker context definition')
    step_result = create_data_from_definition(step_params)
    params['context'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = load_course_tracker_settings(step_params)
    params['settings'] = step_result['settings']

    step_params = {}
    step_params.update(params)
    step_result = create_wpf_application(step_params)
    params['application'] = step_result['application']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = reload_course_tracker_data(step_params)
    params['course tracker data'] = step_result['course tracker data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['data'] = params['course tracker data']
    step_params['view'] = knowledge_get('course list view')
    step_params['title'] = 'Course Tracker'
    step_params['parent context'] = None
    step_result = open_view(step_params)
    params['window'] = step_result['window']

    step_params = {}
    step_params.update(params)
    step_params['application'] = params['application']
    step_params['window'] = params['window']
    step_result = run_application(step_params)

    results = {}
    return results

  def run_course_tracker_server(params):

    step_params = {}
    step_params.update(params)
    step_params['definition'] = knowledge_get('course tracker context definition')
    step_result = create_data_from_definition(step_params)
    params['context'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = load_course_tracker_settings(step_params)
    params['settings'] = step_result['settings']

    step_params = {}
    step_params.update(params)
    step_result = create_wpf_application(step_params)
    params['application'] = step_result['application']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = reload_course_tracker_data(step_params)
    params['course tracker data'] = step_result['course tracker data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['handler'] = 'handle course tracker server request'
    step_params['port'] = 23423
    step_result = start_server(step_params)

    step_params = {}
    step_params.update(params)
    step_params['application'] = params['application']
    step_params['window'] = None
    step_result = run_application(step_params)

    results = {}
    return results

  def save_course_data(params):
    params['view context'] = params['context']
    params['course data'] = params['data']

    step_params = {}
    step_params.update(params)
    step_result = get_current_time(step_params)
    params['current time'] = step_result['current time']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course data']
    step_params['value'] = params['current time']
    step_params['key'] = 'last update time'
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['view context']
    step_params['key'] = 'app context'
    step_result = get_value(step_params)
    params['context'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'data'
    step_result = get_value(step_params)
    params['data'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['data']
    step_params['key'] = 'courses'
    step_result = get_value(step_params)
    params['courses'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course data']
    step_params['key'] = 'id'
    step_result = get_value(step_params)
    params['course id'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['list'] = params['courses']
    step_params['id value'] = params['course id']
    step_params['id definition'] = 'id'
    step_result = get_item_by_id(step_params)
    params['prev course data'] = step_result['item']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['course data']
    step_params['previous data'] = params['prev course data']
    step_result = get_changes(step_params)
    params['course changes'] = step_result['changes']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course changes']
    step_params['value'] = params['course id']
    step_params['key'] = 'id'
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['course changes']
    step_params['template'] = [{'courses': ['param1']}]
    step_params['param2'] = None
    step_params['param3'] = None
    step_result = make_data(step_params)
    params['change list'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['data change history', 'last change number']
    step_result = get_value(step_params)
    params['last change number'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['settings', 'is networking']
    step_result = get_value(step_params)
    params['is networking'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['context']
    step_params['param2'] = params['change list']
    step_params['param3'] = params['last change number']
    step_params['template'] = {'last change number': 'param3', 'change list': 'param2', 'context': 'param1'}
    step_result = make_data(step_params)
    params['parameters'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['parameters']
    step_params['alternative_value'] = params['is networking']
    step_params['alternative_actions'] = [{'ACTION': 'sync course tracker changes with server', 'VALUE': True}]
    step_result = do_alternatively(step_params)
    params['results'] = step_result['results']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['results']
    step_params['key'] = 'change list'
    step_result = get_value(step_params)
    params['change list'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['change list'] = params['change list']
    step_params['last change number'] = params['last change number']
    step_result = sync_course_tracker_changes(step_params)

    results = {}
    return results

  def save_course_tracker_data(params):

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['course tracker data'] = params['course tracker data']
    step_result = save_course_tracker_data_to_file(step_params)

    results = {}
    return results

  def save_course_tracker_data_to_file(params):

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_result = get_course_tracker_data_storage_path(step_params)
    params['storage path'] = step_result['storage path']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['course tracker data']
    step_params['path'] = params['storage path']
    step_result = save_yaml_data_to_file(step_params)

    step_params = {}
    step_params.update(params)
    step_params['storage path'] = params['storage path']
    step_result = get_course_tracker_data_change_history_path(step_params)
    params['history path'] = step_result['history path']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'data change history'
    step_result = get_value(step_params)
    params['data change history'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['data change history']
    step_params['path'] = params['history path']
    step_result = save_yaml_data_to_file(step_params)

    results = {}
    return results

  def save_course_tracker_settings(params):

    step_params = {}
    step_params.update(params)
    step_params['path'] = 'settings.yaml'
    step_result = map_path_relative_to_application(step_params)
    params['path'] = step_result['path']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'settings'
    step_result = get_value(step_params)
    params['settings'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['settings']
    step_params['path'] = params['path']
    step_result = save_yaml_data_to_file(step_params)

    results = {}
    return results

  def save_data_by_name(params):

    step_params = {}
    step_params.update(params)
    step_params['data_name'] = params['data_name']
    step_result = get_yaml_data_path(step_params)
    params['data_path'] = step_result['data_path']

    step_params = {}
    step_params.update(params)
    step_params['kpiece'] = params['data']
    step_result = convert_to_yaml(step_params)
    params['text'] = step_result['yaml']

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['data_path']
    step_params['text'] = params['text']
    step_result = write_file_text(step_params)

    results = {}
    return results

  def save_yaml_data_to_file(params):

    step_params = {}
    step_params.update(params)
    step_params['kpiece'] = params['data']
    step_result = convert_to_yaml(step_params)
    params['text'] = step_result['yaml']

    step_params = {}
    step_params.update(params)
    step_params['path'] = params['path']
    step_params['text'] = params['text']
    step_result = write_file_text(step_params)

    results = {}
    return results

  def send_course_tracker_request_to_server(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['settings', 'server url']
    step_result = get_value(step_params)
    params['server url'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['server url'] = params['server url']
    step_params['request'] = params['request']
    step_result = send_yaml_request_to_server(step_params)
    params['response'] = step_result['response']

    results = {}
    results['response'] = params['response']
    return results

  def send_yaml_request_to_server(params):

    step_params = {}
    step_params.update(params)
    step_params['kpiece'] = params['request']
    step_result = convert_to_yaml(step_params)
    params['request_yaml'] = step_result['yaml']

    def EXEC1(server_url, request_yaml, ):
      from System import Uri
      from System.Net.Sockets import TcpClient
      from System.IO import StreamWriter
      from System.IO import StreamReader
      uri = Uri(server_url)
      with TcpClient(uri.Host, uri.Port if not uri.IsDefaultPort else 23423) as client:
        with client.GetStream() as stream:
          with StreamWriter(stream) as writer:
            with StreamReader(stream) as reader:
              writer.WriteLine(request_yaml)
              write_to_log(request_yaml)
              writer.WriteLine()
              writer.Flush()
              response_yaml = reader.ReadToEnd()
              write_to_log(response_yaml)
      return locals()
    step_result = EXEC1(params['server url'], params['request_yaml'], )
    params['response_yaml'] = step_result['response_yaml']

    step_params = {}
    step_params.update(params)
    step_params['yaml_content'] = params['response_yaml']
    step_result = load_yaml_in_python(step_params)
    params['response'] = step_result['result']

    results = {}
    results['response'] = params['response']
    return results

  def set_course_tracker_storage_path(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'storage path'
    step_result = get_value(step_params)
    params['storage path'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['value'] = params['storage path']
    step_params['key'] = ['view context', 'app context', 'settings', 'storage path']
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['view context', 'app context']
    step_result = get_value(step_params)
    params['app context'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['app context']
    step_result = reload_course_tracker_data(step_params)

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['app context']
    step_result = save_course_tracker_settings(step_params)

    results = {}
    return results

  def set_id_for_added_data_in_change_list(params):

    def EXEC1(context, change_list, ):
      for changes in change_list:
        for course in changes.get('courses', []):
          if not course.get('id'):
            execute_knowledge_piece('set new course id if added', {'context': context, 'course data': course})
      return locals()
    step_result = EXEC1(params['context'], params['change list'], )
    params.update(step_result)

    results = {}
    return results

  def set_item_by_id(params):

    def EXEC1(id_name, list, item, ):
      item_indices = [index for index in range(len(list)) if list[index].get(id_name) == item.get(id_name)]
      if len(item_indices) > 0:
        for index in item_indices:
          list[index] = item
      else:
        list.append(item)
      return locals()
    step_result = EXEC1(params['id definition'], params['list'], params['item'], )
    params.update(step_result)

    results = {}
    return results

  def set_new_course_id_if_added(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course data']
    step_params['key'] = 'id'
    step_result = get_value(step_params)
    params['course id'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['context']
    step_params['param2'] = params['course data']
    step_params['template'] = {'context': 'param1', 'course data': 'param2'}
    step_params['param3'] = None
    step_result = make_data(step_params)
    params['parameters'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['parameters']
    step_params['alternative_value'] = params['course id']
    step_params['alternative_actions'] = [{'ACTION': 'set new course id to course data', 'VALUE': 0}]
    step_result = do_alternatively(step_params)

    results = {}
    return results

  def set_new_course_id_to_course_data(params):

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'data'
    step_result = get_value(step_params)
    params['course tracker data'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['value'] = params['course tracker data']
    step_params['default value'] = {}
    step_result = default_if_None(step_params)
    params['course tracker data'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course tracker data']
    step_params['key'] = 'next course id'
    step_result = get_value(step_params)
    params['next course id'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['value'] = params['next course id']
    step_params['default value'] = 1
    step_result = default_if_None(step_params)
    params['next course id'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course data']
    step_params['value'] = params['next course id']
    step_params['key'] = 'id'
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['value'] = params['next course id']
    step_result = increment(step_params)
    params['next course id'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['course tracker data']
    step_params['value'] = params['next course id']
    step_params['key'] = 'next course id'
    step_result = set_value(step_params)

    results = {}
    return results

  def set_value(params):

    def EXEC1(value, key, dictionary, ):
      if type(key) is not list:
        key = [key]
      if len(key) > 0:
        d = dictionary
        for key_part in key[0:-1]:
          d = d[key_part]
        d[key[-1]] = value
      return locals()
    step_result = EXEC1(params['value'], params['key'], params['dictionary'], )
    params.update(step_result)

    results = {}
    return results

  def show_open_file_dialog(params):

    def EXEC1(initial_path, ):
      import clr
      clr.AddReferenceByPartialName('PresentationFramework')
      from System.IO import Path
      from Microsoft.Win32 import OpenFileDialog
      
      dir = Path.GetDirectoryName(initial_path)
      filename = Path.GetFileName(initial_path)
      
      dlg = OpenFileDialog()
      dlg.DefaultExt = '.*'
      dlg.Filter = 'All files (*.*)|*.*'
      dlg.InitialDirectory = dir
      dlg.FileName = filename
      
      result = dlg.ShowDialog()
      
      if result:
        path = dlg.FileName
        is_ok = True
      else:
        path = initial_path
        is_ok = False
      return locals()
    step_result = EXEC1(params['initial path'], )
    params['path'] = step_result['path']
    params['is ok'] = step_result['is_ok']

    results = {}
    results['path'] = params['path']
    results['is ok'] = params['is ok']
    return results

  def start_from__net_host(params):

    step_params = {}
    step_params.update(params)
    step_result = load__net_host_settings(step_params)
    params['settings'] = step_result['settings']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['settings']
    step_params['key'] = knowledge_get_or_literal('ProjectName')
    step_result = get_value(step_params)
    params['value'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['project name'] = params['value']
    step_result = start_project_from__net_host(step_params)

    results = {}
    return results

  def start_project_from__net_host(params):

    step_params = {}
    step_params.update(params)
    step_params['alternative_value'] = params['project name']
    step_params['context'] = knowledge_get_or_literal('None')
    step_params['alternative_actions'] = knowledge_get_or_literal('.net project start alternatives')
    step_result = do_alternatively(step_params)

    results = {}
    return results

  def start_server(params):

    def EXEC1(handler, port, context, ):
      def dummy(context, handler, port):
        from System.Net.Sockets import TcpListener
        from System.Threading import Thread
        from System.Threading import ThreadStart
        from System.Threading import ParameterizedThreadStart
        from System.IO import StreamReader
        from System.IO import StreamWriter
      
        def connection_thread_func(client):
          try:
            with client.GetStream() as stream:
              with StreamReader(stream) as reader:
                with StreamWriter(stream) as writer:
                  while True:
                    request_lines = []
                    is_header_passed = False
                    while True:
                      line = reader.ReadLine()
                      if line is None:
                        break
                      write_to_log(line)
                      if len(request_lines) == 0 and line == '':
                        continue
                      # HACK
                      if line == '':
                        break
                      if not is_header_passed:
                        if line == '':
                          is_header_passed = True
                      else:
                        if line == '':
                          break
                      request_lines.append(line)
                    request = '\r\n'.join(request_lines)
                    try:
                      response = execute_knowledge_piece(handler, {'context': context, 'request text': request})['response text']
                    except:
                      writer.Write('error')
                      writer.Flush()
                      raise
                    else:
                      writer.Write(response)
                      writer.Flush()
                      break
          except:
            import traceback
            write_to_log(to_html(traceback.format_exc()))
      
        def server_thread_func():
          try:
            listener = TcpListener(port)
            listener.Start()
            try:
              while True:
                client = listener.AcceptTcpClient()
                connection_thread = Thread(ParameterizedThreadStart(connection_thread_func), Name = 'connection', IsBackground = True)
                connection_thread.Start(client)
            finally:
              listener.Stop()
          except:
            import traceback
            write_to_log(to_html(traceback.format_exc()))
      
        server_thread = Thread(ThreadStart(server_thread_func), Name = 'server', IsBackground = True)
        server_thread.Start()
        return server_thread
      server = dummy(context, handler, port)
      return locals()
    step_result = EXEC1(params['handler'], params['port'], params['context'], )
    params.update(step_result)

    results = {}
    results['server'] = params['server']
    return results

  def sync_course_tracker_changes(params):
    params['client last change number'] = params['last change number']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['change list'] = params['change list']
    step_result = set_id_for_added_data_in_change_list(step_params)

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = 'data'
    step_result = get_value(step_params)
    params['data'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['data']
    step_params['change list'] = params['change list']
    step_result = apply_change_list(step_params)
    params['data'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['value'] = params['data']
    step_params['key'] = 'data'
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['data change history', 'history']
    step_result = get_value(step_params)
    params['history'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['list'] = params['history']
    step_params['items'] = params['change list']
    step_result = append_items_to_list(step_params)

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['key'] = ['data change history', 'last change number']
    step_result = get_value(step_params)
    params['last change number'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['collection'] = params['change list']
    step_result = get_length(step_params)
    params['number of changes'] = step_result['length']

    step_params = {}
    step_params.update(params)
    step_params['value1'] = params['last change number']
    step_params['value2'] = params['number of changes']
    step_result = add(step_params)
    params['last change number'] = step_result['result']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['context']
    step_params['value'] = params['last change number']
    step_params['key'] = ['data change history', 'last change number']
    step_result = set_value(step_params)

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['course tracker data'] = params['data']
    step_result = save_course_tracker_data(step_params)

    step_params = {}
    step_params.update(params)
    step_params['data'] = params['data']
    step_params['history'] = params['history']
    step_params['start'] = params['client last change number']
    step_params['end'] = params['last change number']
    step_result = get_change_list(step_params)
    params['change list'] = step_result['change list']

    results = {}
    results['change list'] = params['change list']
    results['last change number'] = params['last change number']
    return results

  def sync_course_tracker_changes_with_server(params):

    step_params = {}
    step_params.update(params)
    step_params['param1'] = params['change list']
    step_params['param2'] = params['last change number']
    step_params['template'] = {'command': 'sync changes', 'data': {'last change number': 'param2', 'change list': 'param1'}}
    step_params['param3'] = None
    step_result = make_data(step_params)
    params['request'] = step_result['data']

    step_params = {}
    step_params.update(params)
    step_params['context'] = params['context']
    step_params['request'] = params['request']
    step_result = send_course_tracker_request_to_server(step_params)
    params['response'] = step_result['response']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['response']
    step_params['key'] = 'change list'
    step_result = get_value(step_params)
    params['change list'] = step_result['value']

    step_params = {}
    step_params.update(params)
    step_params['dictionary'] = params['response']
    step_params['key'] = 'last change number'
    step_result = get_value(step_params)
    params['last change number'] = step_result['value']

    results = {}
    results['change list'] = params['change list']
    results['last change number'] = params['last change number']
    return results

  def write__net_exception_to_log(params):

    def EXEC1(exception, ):
      write_to_log('<div><pre>%s</pre></div>' % html_encode(exception.ToString()))
      data = dict(exception.Data)
      write_to_log('<div><pre>%s</pre></div>' % html_encode(to_yaml(data)))
      #info = dir(exception.Data['PythonExceptionInfo'].Value)
      #write_to_log('<div><pre>%s</pre></div>' % html_encode(info))
      return locals()
    step_result = EXEC1(params['exception'], )
    params.update(step_result)

    results = {}
    return results

  def write_file_text(params):

    def EXEC1(path, text, ):
      from System.IO import Directory
      from System.IO import File
      from System.IO import Path
      dir = Path.GetDirectoryName(path)
      if not Directory.Exists(dir):
        Directory.CreateDirectory(dir)
      File.WriteAllText(path, text)
      return locals()
    step_result = EXEC1(params['path'], params['text'], )
    params.update(step_result)

    results = {}
    return results

  def write_python_exception_to_log(params):

    def EXEC1():
      import traceback
      write_to_log('<div><pre>%s</pre></div>' % html_encode(traceback.format_exc()))
      return locals()
    step_result = EXEC1()
    params.update(step_result)

    results = {}
    return results

  def _write_to_log(params):

    step_params = {}
    step_params.update(params)
    step_params['kpiece'] = params['data']
    step_result = convert_to_yaml(step_params)
    params['yaml'] = step_result['yaml']

    def EXEC1(yaml, data, ):
      write_to_log(to_html(yaml))
      return locals()
    step_result = EXEC1(params['yaml'], params['data'], )
    params.update(step_result)

    results = {}
    return results

  names = {

    'add': add,
    'add addition': add_addition,
    'add cancellation': add_cancellation,
    'add new course': add_new_course,
    'append items to list': append_items_to_list,
    'append to list': append_to_list,
    'apply change list': apply_change_list,
    'apply changes inplace': apply_changes_inplace,
    'apply common attributes to wpf element': apply_common_attributes_to_wpf_element,
    'calculate course schedule data': calculate_course_schedule_data,
    'calculate schedule dates': calculate_schedule_dates,
    'cancel selected lessons': cancel_selected_lessons,
    'choose storage path': choose_storage_path,
    'clone data': clone_data,
    'convert date to date with weekday': convert_date_to_date_with_weekday,
    'convert schedule to string': convert_schedule_to_string,
    'convert string to date': convert_string_to_date,
    'convert string to datetime': convert_string_to_datetime,
    'convert string to schedule': convert_string_to_schedule,
    'convert to yaml': convert_to_yaml,
    'create data from definition': create_data_from_definition,
    'create wpf application': create_wpf_application,
    'create wpf binding': create_wpf_binding,
    'create wpf element for column': create_wpf_element_for_column,
    'create wpf element for command': create_wpf_element_for_command,
    'create wpf element for data field': create_wpf_element_for_data_field,
    'create wpf element for dock panel': create_wpf_element_for_dock_panel,
    'create wpf element for horizontal grid': create_wpf_element_for_horizontal_grid,
    'create wpf element for list': create_wpf_element_for_list,
    'create wpf element for menu': create_wpf_element_for_menu,
    'create wpf element for menu item': create_wpf_element_for_menu_item,
    'create wpf element for unknown': create_wpf_element_for_unknown,
    'create wpf element for vertical grid': create_wpf_element_for_vertical_grid,
    'create wpf element for wrap panel': create_wpf_element_for_wrap_panel,
    'default if None': default_if_None,
    'delete addition': delete_addition,
    'delete cancellation': delete_cancellation,
    'delete from list': delete_from_list,
    'delete selected course': delete_selected_course,
    'do alternatively': do_alternatively,
    'execute command wpf': execute_command_wpf,
    'execute knowledge piece': _execute_knowledge_piece,
    'get change list': get_change_list,
    'get changes': get_changes,
    'get course tracker courses': get_course_tracker_courses,
    'get course tracker data change history path': get_course_tracker_data_change_history_path,
    'get course tracker data storage path': get_course_tracker_data_storage_path,
    'get current time': get_current_time,
    'get item by id': get_item_by_id,
    'get length': get_length,
    'get selected data from list': get_selected_data_from_list,
    'get value': get_value,
    'get yaml data path': get_yaml_data_path,
    'handle course tracker server request': handle_course_tracker_server_request,
    'handle sync course tracker changes request': handle_sync_course_tracker_changes_request,
    'increment': increment,
    'load .net host settings': load__net_host_settings,
    'load course tracker data': load_course_tracker_data,
    'load course tracker data from file': load_course_tracker_data_from_file,
    'load course tracker data from server': load_course_tracker_data_from_server,
    'load course tracker settings': load_course_tracker_settings,
    'load data by name': load_data_by_name,
    'load yaml data from file': load_yaml_data_from_file,
    'load yaml in python': load_yaml_in_python,
    'make data': make_data,
    'make wpf element from view': make_wpf_element_from_view,
    'map path relative to application': map_path_relative_to_application,
    'open course details': open_course_details,
    'open view': open_view,
    'read file text': read_file_text,
    'reload course tracker data': reload_course_tracker_data,
    'run application': run_application,
    'run course tracker': run_course_tracker,
    'run course tracker server': run_course_tracker_server,
    'save course data': save_course_data,
    'save course tracker data': save_course_tracker_data,
    'save course tracker data to file': save_course_tracker_data_to_file,
    'save course tracker settings': save_course_tracker_settings,
    'save data by name': save_data_by_name,
    'save yaml data to file': save_yaml_data_to_file,
    'send course tracker request to server': send_course_tracker_request_to_server,
    'send yaml request to server': send_yaml_request_to_server,
    'set course tracker storage path': set_course_tracker_storage_path,
    'set id for added data in change list': set_id_for_added_data_in_change_list,
    'set item by id': set_item_by_id,
    'set new course id if added': set_new_course_id_if_added,
    'set new course id to course data': set_new_course_id_to_course_data,
    'set value': set_value,
    'show open file dialog': show_open_file_dialog,
    'start from .net host': start_from__net_host,
    'start project from .net host': start_project_from__net_host,
    'start server': start_server,
    'sync course tracker changes': sync_course_tracker_changes,
    'sync course tracker changes with server': sync_course_tracker_changes_with_server,
    'write .net exception to log': write__net_exception_to_log,
    'write file text': write_file_text,
    'write python exception to log': write_python_exception_to_log,
    'write to log': _write_to_log,
  }
  return names
names = dummy()